const path = require('path')
const webpack = require('webpack')
const CompressionPlugin = require('compression-webpack-plugin')
const zlib = require('zlib')

const isProd = process.env.NODE_ENV === 'production'
const isTest = process.env.NODE_ENV === 'test'

// 默认开启编译器以保证老项目兼容；确认不需要后可改为 false
const useCompiler = true

module.exports = {
  filenameHashing: true,
  productionSourceMap: false,
  publicPath: './',
  lintOnSave: false,
  runtimeCompiler: !!useCompiler,

  chainWebpack: (config) => {
    // 仅删除 prefetch（存在时才删除），保留 preload
    if (config.plugins.has && config.plugins.has('prefetch')) {
      config.plugins.delete('prefetch')
    }
    // 独立 runtime，利于缓存稳定
    if (config.optimization && typeof config.optimization.runtimeChunk === 'function') {
      config.optimization.runtimeChunk('single')
    }

    // 图片构建期压缩（仅生产/测试）
    if (isProd || isTest) {
      try {
        config.module
          .rule('images')
          .use('image-webpack')
          .loader('image-webpack-loader')
          .options({
            mozjpeg: { progressive: true, quality: 78 },
            // 使用 pngquant，关闭 optipng，速度更快
            optipng: { enabled: false },
            pngquant: { quality: [0.6, 0.8], speed: 3 },
            gifsicle: { interlaced: false },
            svgo: { plugins: [{ removeViewBox: false }, { cleanupIDs: true }] },
            webp: { quality: 80 }
          })
          .end()
      } catch (e) {
        // 老项目或缺少 image-webpack-loader 时跳过
      }
    }
  },

  configureWebpack: {
    optimization: {
      minimize: isProd || isTest,
      splitChunks: {
        chunks: 'all',
        minSize: 20000,
        maxSize: 500000,
        minChunks: 1,
        maxAsyncRequests: 30,
        maxInitialRequests: 30,
        cacheGroups: {
          vue: {
            test: (m) => /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-vue',
            priority: 30,
            reuseExistingChunk: true
          },
          elementUI: {
            test: (m) => /[\\/]node_modules[\\/](element-ui|@hui[\\/]+element)[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-element',
            priority: 25,
            reuseExistingChunk: true
          },
          vxeTable: {
            test: (m) => /[\\/]node_modules[\\/](vxe-table|xe-utils)[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-vxe',
            priority: 25,
            reuseExistingChunk: true
          },
          tinymce: {
            test: (m) => /[\\/]node_modules[\\/](@tinymce|tinymce)[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-tinymce',
            priority: 25,
            reuseExistingChunk: true
          },
          libs: {
            test: (m) => /[\\/]node_modules[\\/](axios|xlsx|file-saver|print-js)[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-libs',
            priority: 20,
            reuseExistingChunk: true
          },
          vendors: {
            test: (m) => /[\\/]node_modules[\\/]/.test(m.resource || m.context || ''),
            name: 'chunk-vendors',
            priority: 10,
            minChunks: 1,
            reuseExistingChunk: true
          },
          commons: {
            name: 'chunk-commons',
            minChunks: 2,
            priority: 5,
            reuseExistingChunk: true
          }
        }
      }
    },

    resolve: {
      extensions: ['.js', '.vue', '.json'],
      alias: {
        '@': path.resolve(__dirname, './src'),
        static: path.resolve(__dirname, './public/static/'),
        // 使用完整版构建（含编译器），以保证老项目兼容
        'vue$': 'vue/dist/vue.esm.js'
      }
    },

    output: isProd || isTest ? {
      filename: 'js/[name].[contenthash:8].js',
      chunkFilename: 'js/[name].[contenthash:8].js'
    } : {
      filename: 'js/[name].js',
      chunkFilename: 'js/[name].js'
    },

    plugins: [
      ...(isProd || isTest ? [
        // 生成 gzip 预压缩文件（与 compression-webpack-plugin v3/4/5 兼容）
        new CompressionPlugin({
          test: /\.(js|css|html|svg|json|ttf|woff2?)$/,
          threshold: 1024,
          deleteOriginalAssets: false,
          minRatio: 0.9
        })
      ] : []),

      new webpack.IgnorePlugin({
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/
      })
    ],

    performance: {
      hints: isProd ? 'warning' : false,
      maxEntrypointSize: 512000,
      maxAssetSize: 512000
    }
  },

  css: {
    sourceMap: !isProd && !isTest
  },

  devServer: {
    compress: true
  }
}
